package com.hbnrtech.sip.gb28181.config;

/**
 * @author liuduo
 * @date 2025-04-21 10:16
 */

import com.hbnrtech.sip.gb28181.stack.GbStringMsgParserFactory;
import gov.nist.javax.sip.SipStackImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sip.PeerUnavailableException;
import javax.sip.SipFactory;
import javax.sip.SipStack;
import javax.sip.address.AddressFactory;
import javax.sip.header.HeaderFactory;
import javax.sip.message.MessageFactory;
import java.util.Properties;

@Configuration
@Slf4j
public class SipLayerConfig {

    @Bean
    public SipFactory sipFactory() {
        SipFactory sipFactory = SipFactory.getInstance();
        sipFactory.setPathName("gov.nist"); // 使用 NIST-SIP 实现
        return sipFactory;
    }

    @Bean
    public HeaderFactory headerFactory() throws PeerUnavailableException {
        return sipFactory().createHeaderFactory();
    }

    @Bean
    public AddressFactory addressFactory() throws PeerUnavailableException {
        return sipFactory().createAddressFactory();
    }

    @Bean
    public MessageFactory messageFactory() throws PeerUnavailableException {
        return sipFactory().createMessageFactory();
    }

    @Bean
    public SipStack sipStack(SipFactory sipFactory) throws PeerUnavailableException {
        Properties properties = new Properties();
        properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
      //  properties.setProperty("javax.sip.IP_ADDRESS", sipConfigProperties.getIp());
        // 自动处理对话(dialog)和事务(transaction)
        properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); // GB28181通常自己管理
        // 接收所有notify请求，即使没有订阅
        properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
        properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
        properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");

        // 为_NULL _对话框传递_终止的_事件
        properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");

        // 获取实际内容长度，不使用header中的长度信息
        properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");

        // 会话清理策略
        properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");

        // 当 SIP 连接在设定的时间内（此处为 60 秒）没有数据传输，系统会主动关闭该连接，释放资源
        properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");

        // 启用可重入监听器模式（线程安全增强）
        // 功能：允许同一监听器实例同时处理多个事件，避免并发问题
        // 影响：当有高并发请求时，能更安全地处理事件回调
        // 注意：需确保监听器实现是线程安全的
        properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");

        // 线程审计间隔配置（系统健康监控）
        // 功能：设置线程池状态检查间隔为30秒(30000毫秒)
        // 作用：定期检测线程泄漏、死锁等异常情况
        // 建议：生产环境建议保持开启，调试时可适当缩短间隔
        properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");

        // 网络I/O处理模式配置（性能关键）
        // 功能：使用NIO(非阻塞I/O)模型的消息处理器
        // 优势：支持更高的并发连接数，适用于高吞吐量场景
        // 对比：区别于传统的阻塞式OIO模型
        properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "gov.nist.javax.sip.stack.NioMessageProcessorFactory");

        // SIP消息体记录开关（安全敏感配置）
        // 功能：启用完整SIP消息内容记录（包括消息头和SDP正文）
        // 用途：调试时查看原始报文，生产环境建议关闭
        // 警告：会记录SIP消息中的敏感信息（如认证信息）
        properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");

        // NIST-SIP 特有的属性，可以调整日志等
        properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO"); // 或 DEBUG
        properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip-server.log");
        properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip-debug.log");

        SipStackImpl sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
        sipStack.setMessageParserFactory(new GbStringMsgParserFactory());
        return sipStack;
    }
}
